#ifndef WINDOWGROUPS_H
#define WINDOWGROUPS_H

#include <Windows.h>
#include <WindowsX.h>
#include <map>
#include <set>
#include <ctype.h>

#include "CustomWindow.h"
#include "CassiopeiaComponent.h"
#include "PaintedButton.h"
#include "resource.h"
#include "SmoothWindowSideAnimation.h"
#include "WindowVisibilityHelper.h"
#include "Translation.h"
#include "Settings.h"

using namespace std;
using namespace Translation;

class WindowGroups : public CassiopeiaComponent, public CustomWindow
{
public:
	typedef void (*GroupNameChangedProc)(WindowGroups* sender, int groupID, tstring newName);
	typedef void (*GroupSwitchingProc)(WindowGroups* sender, int switchToGroupID, bool* cancel);

	WindowGroups();
	~WindowGroups();
	void Create(HINSTANCE hInstance);
	CCState Activate();
	CCState Deactivate();

	void GroupNameChanged(GroupNameChangedProc ptr);
	void GroupSwitching(GroupSwitchingProc ptr);
	void MoveWindowToGroup(int groupID, HWND hWnd);
	void ExcludeWindow(HWND hWnd, bool exclude);
	bool IsWindowExcluded(HWND hWnd);
	map<int, tstring> GetGroups();
	int GetCurrentGroup();
	void Reset();
	void SetTag(LPVOID tag);
	LPVOID GetTag();
private:
	void SetGroupName(int groupID, tstring name);
	bool SwitchToGroup(int groupID);

	void Open(bool value);
	void ToggleOpen();
	bool HandleGroupButtonWndProcs(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
	void HandleGroupButtonsPainting(HDC hdc);
	void ChangeDwmCompatibleLayout();
	void LoadSettings();
	void SaveSettings();

	bool opened;
	bool hotkeyOpened;

	int lastGroupID;
	int normalHeight;
	int openedHeight;
	POINT location;
	int currentGroupID;
	int tmpGroupIDForRenaming;

	LPVOID tag;
	HMENU groupMenu;

	GroupNameChangedProc onGroupNameChangedPtr;
	GroupSwitchingProc onGroupSwitchingPtr;

	PaintedButton* buttonOpen;
	SmoothWindowSideAnimation *animation;
	WindowVisibilityHelper* windowVisibilityHelper;

	set<HWND> excludedHWnds;
	map<int, PaintedButton*> groupButtons;
	map<int, set<HWND>> hiddenHWnds;
	map<int, tstring> groups;

	static void buttonOpen_Clicked(PaintedButton* sender, LPVOID tag);
	static void groupButton_Clicked(PaintedButton* sender, LPVOID tag);
	static void groupButton_RightMouseButtonUp(PaintedButton* sender, LPVOID tag);
	
	static BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam);
	static LRESULT CALLBACK WndProc(LPVOID sender, HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
	static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
};

#endif